package com.zygh.lz.stapprove;

import cn.hutool.core.util.IdUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.zygh.lz.dao.OperationMapper;
import com.zygh.lz.entity.Operation;
import org.apache.commons.lang.StringUtils;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Method;
import java.net.URLDecoder;
import java.util.Arrays;
import java.util.Map;


/**
 * 系统日志：切面处理类
 */
@Aspect
@Component
public class SysLogAspect {

    private static final Logger log = LoggerFactory.getLogger(SysLogAspect.class);

    @Resource
    private OperationMapper operationMapper;


    //定义切点 @Pointcut
    //在注解的位置切入代码
    @Pointcut("@annotation(com.zygh.lz.stapprove.ViLog)")
    public void logPoinCut() {
    }

    //切面 配置通知
    @AfterReturning(value = "logPoinCut()")
    public void saveOperation(JoinPoint joinPoint) {
        //log.info("---------------接口日志记录---------------");
        //保存日志
        Operation operation = new Operation();
        //从切面织入点处通过反射机制获取织入点处的方法
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        //获取切入点所在的方法
        Method method = signature.getMethod();
        //获取操作--方法上的ViLog的值
        ViLog viLog = method.getAnnotation(ViLog.class);
        if (viLog != null) {
            //保存操作事件、日志类型
            String logType = viLog.logType();
            operation.setLogType(logType);
            //功能模块
            String module = viLog.module();
            operation.setModule(module);

        }
        HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
        // 客户端ip
        String ip = getRemoteIP(request);


        JSONObject jsonObject = new JSONObject();
        try {
            //--------请求头数据-------------
            String s = request.getHeader("userCredential");
            s = URLDecoder.decode(s, "utf-8");
            jsonObject = JSONObject.parseObject(s);
            JSONObject userInfo;
            userInfo = jsonObject.getJSONObject("credential").getJSONObject("load").getJSONObject("userInfo");
            //身份证号
            operation.setCardNo(userInfo.getString("sfzh"));
            //警号
            operation.setPoliceId(userInfo.getString("jh"));
        } catch (Exception e) {
            log.info("用户为空");
        }

        //--------请求头数据-------------
        try {
            String sn = jsonObject.getJSONObject("credential").getJSONObject("serverSign").getString("sn");
            if (StringUtils.isEmpty(sn)) {
                operation.setState(1);
            }
            operation.setSn(sn);
        } catch (Exception e) {
            log.info("证书获取失败");
        }

        operation.setRequestId(IdUtil.simpleUUID());
        // 数据来源id
        operation.setSource("50");

        try {
            String url = jsonObject.getJSONObject("credential").getJSONObject("serverSign").getString("url");
            operation.setUri(url);
            operation.setUrl(url);
        } catch (Exception e) {
            log.info("url为空");
        }

        //浏览器唯一标识
        String sessionId = request.getSession().getId();
        operation.setSessionId(sessionId);
        // 拦截的方法参数
        String param = Arrays.toString(joinPoint.getArgs());
        if (param.length() > 67680) {
            param = "";
        }

        //响应数据
        String result = JSON.toJSONString(request.getAttribute("result"));
        if (result.equals("")) {
            operation.setResponse("500");
        } else {
            operation.setResponse("200");
        }

        operation.setResponseType("1");
        try {
            Map<String, String> map = (Map<String, String>) JSON.parse(result);
            if (String.valueOf(map.get("code")).equals("1") || String.valueOf(map.get("code")).equals("200")) {
                operation.setResult("成功");
                operation.setErrorCode("");
                operation.setErrorLog("");
            } else {
                operation.setResult("失败");
                operation.setErrorCode((map.get("code")));
                operation.setErrorLog(map.get("msg"));
            }
        } catch (Exception e) {
            operation.setResult("成功");
            operation.setErrorCode("");
            operation.setErrorLog("");
        }
        operation.setParams(param);
        operation.setFormatParam(param);
        operation.setTerminalIp(ip);
        operation.setRequestId(IdUtil.simpleUUID());
        operation.setContent(viLog.module());
        operation.setResponseTime(1);
        operation.setSourceIp(ip);
        operation.setSourcePort(request.getRemotePort());

        operation.setDestIp("62.66.6.163");
        operation.setDestPort(8090);
        operation.setTime(System.currentTimeMillis());
        operation.setState(0);
        operationMapper.insertSelective(operation);

    }

    /**
     * 获取请求服务ip
     *
     * @param request 参数
     * @return String
     */
    public static String getRemoteIP(HttpServletRequest request) {
        String ip = null;
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("X-Forwarded-For");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("Proxy-Client-IP");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("WL-Proxy-Client-IP");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getRemoteAddr();
        }

        if (ip != null) {
            //对于通过多个代理的情况，最后IP为客户端真实IP,多个IP按照','分割
            int position = ip.indexOf(",");
            if (position > 0) {
                ip = ip.substring(0, position);
            }
        }
        return ip;
    }


    //定义移动端请求的所有可能类型
    private static final String[] agent = {"Android", "iPhone", "iPod", "iPad", "Windows Phone", "MQQBrowser"};

    /**
     * 判断User-Agent 是不是来自于手机
     *
     * @param ua
     * @return
     */
    public static boolean checkAgentIsMobile(String ua) {
        boolean flag = false;
        if (!ua.contains("Windows NT") || (ua.contains("Windows NT") && ua.contains("compatible; MSIE 9.0;"))) {
            // 排除 苹果桌面系统
            if (!ua.contains("Windows NT") && !ua.contains("Macintosh")) {
                for (String item : agent) {
                    if (ua.contains(item)) {
                        flag = true;
                        break;
                    }
                }
            }
        }
        return flag;
    }
}
